home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
assign manager
/
assignwedge
/
source
/
stackcall.a
< prev
next >
Wrap
Text File
|
1996-04-07
|
3KB
|
141 lines
**
** StackCall.a
**
** Stack swap routines
**
** Copyright © 1990-1994 by Olaf `Olsen' Barthel
** All Rights Reserved
**
include "exec/types.i"
include "exec/tasks.i"
include "exec/memory.i"
include "exec/execbase.i"
include "dos/dos.i"
include "dos/dosextens.i"
*----------------------------------------------------------------------
CALL macro
xref LVO\1
jsr LVO\1(a6)
endm
*----------------------------------------------------------------------
ARG_SUCCESS equ 4+5*4
ARG_STACKSIZE equ ARG_SUCCESS+4
ARG_ARGCOUNT equ ARG_STACKSIZE+4
ARG_ROUTINE equ ARG_ARGCOUNT+4
ARG_ARGS equ ARG_ROUTINE+4
TRUE equ 1
FALSE equ 0
*----------------------------------------------------------------------
csect text,0,0,1,2
*----------------------------------------------------------------------
xdef StackCall
; LONG __stdargs StackCall( LONG *Success,
; LONG StackSize,
; LONG ArgCount,
; LONG (* __stdargs Function)(...),
; ...);
;
; Calls a function with parameters on a newly-allocated
; stack. Caution: assumes all arguments are 32 bits wide.
StackCall:
movem.l d2/d3/a2/a3/a6,-(sp) ; Save registers
move.l ARG_STACKSIZE(sp),d0 ; Get desired stack size
add.l #15+StackSwapStruct_SIZEOF,d0 ; Round to next...
and.l #-16,d0 ; ...quad long word
move.l d0,d2 ; Save it for later
move.l #MEMF_PUBLIC,d1 ; Well?
move.l SysBase(a4),a6 ; Get SysBase
CALL AllocMem ; Allocate the memory
tst.l d0 ; Successful?
beq.b 1$ ; Exit if not
move.l d0,a2 ; Remember base address
add.l #StackSwapStruct_SIZEOF,d0 ; Skip the header
move.l d0,stk_Lower(a2) ; Store the stack lower bound
move.l a2,a3 ; Get the base address
add.l d2,a3 ; Add the allocation size
move.l a3,stk_Upper(a2) ; Store the stack upper bound
move.l ARG_ARGCOUNT(sp),d0 ; Get the number of arguments
beq.b 3$ ; Skip if none
move.l d0,d1
add.l d1,d1 ; One long word per argument
add.l d1,d1
addq.l #4,d1 ; One for predecrement
sub.l d1,a3 ; Pull it down
subq.l #1,d0 ; Subtract one for DBRA
lea.l ARG_ARGS(sp),a0 ; Get the source argument list
move.l a3,a1 ; Get the destination argument list
2$ move.l (a0)+,(a1)+ ; Copy the parameters
dbra d0,2$ ; Loop until all is copied
3$ move.l a3,stk_Pointer(a2) ; Store the new stack pointer
move.l ARG_ROUTINE(sp),a3 ; Get address of the routine to call
move.l a2,a0 ; Swap the stack
CALL StackSwap
jsr (a3) ; Call the routine
move.l d0,d3 ; Save the result
move.l a2,a0 ; Swap the stack
CALL StackSwap
move.l a2,a1 ; Get the base address
move.l d2,d0 ; Get the allocation length
CALL FreeMem ; Free the memory
move.l ARG_SUCCESS(sp),a0 ; Flag as success
move.l #TRUE,(a0)
move.l d3,d0 ; Return the result
movem.l (sp)+,d2/d3/a2/a3/a6 ; Restore registers
rts
1$ move.l ARG_SUCCESS(sp),a0 ; Flag as failure
move.l #FALSE,(a0)
movem.l (sp)+,d2/d3/a2/a3/a6 ; Restore registers
rts
*----------------------------------------------------------------------
dc.l _BSSBAS
dc.l _BSSLEN
*----------------------------------------------------------------------
csect __MERGED,data
xref SysBase
xref _BSSBAS
xref _BSSLEN
*----------------------------------------------------------------------
end